﻿//-----------------------------------------------------------------------
// <copyright>
//     Copyright (c) Artur Mustafin. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

namespace Expressions.Compiler.Internal
{
    using System.Collections.Generic;

    using Interfaces;

    /// <summary>
    /// Tree of the tokens
    /// </summary>
    internal sealed class ExpressionTree<T> : IExpressionTree<T>
    {
        /// <summary>
        /// 
        /// </summary>
        private readonly IExpressionContext<T> _context;

        /// <summary>
        /// 
        /// </summary>
        private readonly IEnumerable<IExpressionTree<T>> _children;

        /// <summary>
        /// 
        /// </summary>
        private readonly int _depth;

        /// <summary>
        /// Initializes a new instance of the <see cref="ExpressionTree"/> class.
        /// </summary>
        /// <param name="depth">The depth.</param>
        /// <param name="node">The node.</param>
        internal ExpressionTree(int depth, IExpressionContext<T> context, IEnumerable<IExpressionTree<T>> children = null)
        {
            _context = context;
            _children = children;
            _depth = depth;
        }

        /// <summary>
        /// Depth of the a node
        /// </summary>
        internal int Depth
        {
            get
            {
                return _depth;
            }
        }

        /// <summary>
        /// Gets the children.
        /// </summary>
        /// <value>The children.</value>
        internal IEnumerable<IExpressionTree<T>> Children
        {
            get
            {
                return _children;
            }
        }

        /// <summary>
        /// Gets the context.
        /// </summary>
        /// <value>The context.</value>
        public IExpressionContext<T> Context
        {
            get
            {
                return _context;
            }
        }

        public IExpressionTree<T> this[int counter]
        {
            get
            {
                if (_children != null)
                {
                    IEnumerator<IExpressionTree<T>> enumerator = _children.GetEnumerator();
                    while (enumerator.MoveNext() && counter >= 0)
                    {
                        if (counter-- == 0)
                        {
                            return enumerator.Current;
                        }
                    }
                }
                return null;
            }
        }

#if TRACE
        public override string ToString()
        {
            return string.Format("[ {0} ] {1}", _context.Token.Name, _context);
        }
#endif
    }

    /// <summary>
    /// Tree of the tokens
    /// </summary>
    internal sealed class ExpressionTree : IExpressionTree
    {
        /// <summary>
        /// 
        /// </summary>
        private readonly IExpressionContext _context;

        /// <summary>
        /// 
        /// </summary>
        private readonly IEnumerable<IExpressionTree> _children;

        /// <summary>
        /// 
        /// </summary>
        private readonly int _depth;

        /// <summary>
        /// Initializes a new instance of the <see cref="ExpressionTree"/> class.
        /// </summary>
        /// <param name="depth">The depth.</param>
        /// <param name="node">The node.</param>
        internal ExpressionTree(int depth, IExpressionContext context, IEnumerable<IExpressionTree> children = null)
        {
            _context = context;
            _children = children;
            _depth = depth;
        }

        /// <summary>
        /// Depth of the a node
        /// </summary>
        internal int Depth
        {
            get
            {
                return _depth;
            }
        }

        /// <summary>
        /// Gets the children.
        /// </summary>
        /// <value>The children.</value>
        internal IEnumerable<IExpressionTree> Children
        {
            get
            {
                return _children;
            }
        }

        /// <summary>
        /// Gets the context.
        /// </summary>
        /// <value>The context.</value>
        public IExpressionContext Context
        {
            get
            {
                return _context;
            }
        }

        public IExpressionTree this[int counter]
        {
            get
            {
                if (_children != null)
                {
                    IEnumerator<IExpressionTree> enumerator = _children.GetEnumerator();
                    while (enumerator.MoveNext() && counter >= 0)
                    {
                        if (counter-- == 0)
                        {
                            return enumerator.Current;
                        }
                    }
                }
                return null;
            }
        }
#if TRACE
        public override string ToString()
        {
            return string.Format("[ {0} ] {1}", _context.Token.Name, _context);
        }
#endif
    }
}
